use axum::{
    extract::{Request, State},
    http::StatusCode,
    middleware::Next,
    response::{IntoResponse, Response},
};

use my_rust_core::{
    constants::{error, server_code},
    security::auth_request_validator,
};

use std::sync::Arc;

use crate::{AppService, handlers::shared};

pub async fn check_auth(
    State(service): State<Arc<AppService>>,
    request: Request,
    next: Next,
) -> Response {
    let granted = auth_request_validator::check_access_permission(
        request.method().as_str(),
        request.uri().to_string().as_str(),
        request
            .headers()
            .get("authorization")
            .map(|h| h.to_str().unwrap_or("")),
        service.user_active_token_manager.clone(),
        service.request_map_query.clone(),
    )
    .await;

    if !granted {
        // If user was authenticated but token is no longer valid or user is not granted for current url 401 code will be sent.
        return shared::get_error_response(
            StatusCode::UNAUTHORIZED,
            server_code::UNAUTHORIZED,
            error::ERROR_USER_ACCOUNT_NOT_AUTHORIZED,
            request.uri().to_string().as_str(),
        )
        .into_response();
    }

    next.run(request).await
}
